package com.panda.admin.login.authconfig;

import com.panda.admin.login.auth.service.impl.SysUserDetailServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.annotation.Resource;

/**
 * author: tcy
 * createDate: 2022/10/27
 * description:安全配置
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private SysUserDetailServiceImpl sysUserDetailService;


    /**
     * 密码编码器
     *
     * 委托方式，根据密码的前缀选择对应的encoder，
     * 例如：{bcypt}前缀->标识BCYPT算法加密；
     *     {noop}->标识不使用任何加密即明文的方式
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        //秘文编辑密码
        //return new BCryptPasswordEncoder();

        //编辑工厂，可用多种方式编辑
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    /**
     * 认证管理器
     */
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 身份验证管理器
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        /**
         * 测试用户，单独提供
         * 只能用这个用户才能登录
         */
        //auth.inMemoryAuthentication()
        //    .withUser("panda")
        //    .password(passwordEncoder().encode("123456"))
        //    .roles("admin");

        /**
         * 这里从数据库查询用户，但是登录方式唯一
         */
        //auth.userDetailsService(sysUserDetailService);

        /**
         * 可以匹配多种登录方式
         * 账号密码、手机验证码、第三方授权等
         */
        auth.authenticationProvider(daoAuthenticationProvider());
      }

    /**
     * 账号密码 认证授权提供者
     */
    @Bean
      public DaoAuthenticationProvider daoAuthenticationProvider(){
          DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
          provider.setUserDetailsService(sysUserDetailService);
          provider.setPasswordEncoder(passwordEncoder());
          provider.setHideUserNotFoundExceptions(false);  //是否隐藏用户不存在异常
          return provider;
      }

    /**
     * 手机验证码认证授权提供者
     */
//    @Bean
//    public SmsCodeAuthenticationProvider smsCodeAuthenticationProvider() {
//        SmsCodeAuthenticationProvider provider = new SmsCodeAuthenticationProvider();
//        provider.setUserDetailsService(memberUserDetailsService);
//        provider.setRedisTemplate(redisTemplate);
//        return provider;
//    }

    /**
     * 微信认证授权提供者
     */
//    @Bean
//    public WechatAuthenticationProvider wechatAuthenticationProvider() {
//        WechatAuthenticationProvider provider = new WechatAuthenticationProvider();
//        provider.setUserDetailsService(memberUserDetailsService);
//        provider.setWxMaService(wxMaService);
//        return provider;
//    }

    /**
     * 配置放行规则
     */
    @Override
    public void configure(WebSecurity http) throws Exception {
        http.ignoring().antMatchers("/swagger-resources", "/v2/api-docs", "/role/**", "/menu/**", "/enroll/**");
    }

//    @Override
//    public void configure(HttpSecurity http) throws Exception {
//        http.csrf().disable()
//            .authorizeRequests()
//            .antMatchers("/admin-login/oauth/**", "/oauth/**", "/doc.html", "/swagger-resources","swagger-ui.html", "/v2/api-docs").permitAll()
//            .anyRequest().authenticated()
//            .and().formLogin();
//    }

    @Override
    @Bean
    public UserDetailsService userDetailsService(){
        return super.userDetailsService();
    }
}
